﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Transactions;
using Abp.Collections.Extensions;
using Abp.Dependency;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Blog.ThirdPartyCallLogs;
using Castle.Core.Logging;
using Castle.DynamicProxy;
using Newtonsoft.Json;

namespace Blog.Interceptors
{
    public class ThirdPartyCallLogInterceptor : AbpInterceptorBase, ITransientDependency
    {
        private readonly IRepository<ThirdPartySystemCallLog, Guid> _thirdPartySystemCallLogRepository;
        private readonly IUnitOfWorkManager _unitOfWorkManager;
        private readonly IThirdPartyCallHelper _thirdPartyCallHelper;

        public ThirdPartyCallLogInterceptor(
            IRepository<ThirdPartySystemCallLog, Guid> thirdPartySystemCallLogRepository,
            IUnitOfWorkManager unitOfWorkManager,
            IThirdPartyCallHelper thirdPartyCallHelper
            )
        {
            _thirdPartySystemCallLogRepository = thirdPartySystemCallLogRepository;
            _unitOfWorkManager = unitOfWorkManager;
            _thirdPartyCallHelper = thirdPartyCallHelper;
        }
        public ILogger Logger { get; set; }

        public override void InterceptSynchronous(IInvocation invocation)
        {
            var customAttribute = invocation.Method.CustomAttributes;
            var attribute = customAttribute.FirstOrDefault(x => x.AttributeType == typeof(ThridPartyCallLogAttribute)); 
            Console.WriteLine($"1.-----第三方日志-同步拦截器");
            
            var thirdPartySystemCallLog = _thirdPartyCallHelper.CreateThirdPartySystemCallLog(invocation);
            string outputParams = string.Empty;
            bool isSuccess = true;
            string errorInfo = string.Empty;
            try
            {
                invocation.Proceed(); //调用方法
                outputParams = JsonConvert.SerializeObject(invocation.ReturnValue);
            }
            catch (Exception e)
            {
                isSuccess = false;
                errorInfo = $"{e.Message}；堆栈信息：{e.StackTrace}";
            }
            finally
            {
                thirdPartySystemCallLog.NatrualKeyId = Guid.Empty;//暂时无法获取
                thirdPartySystemCallLog.SourceSystem = "";//暂时无法获取
            
                thirdPartySystemCallLog.IsSuccess = isSuccess;
                thirdPartySystemCallLog.ResponseData = outputParams;
                thirdPartySystemCallLog.ErrorInfo = errorInfo;

                WriteLog(thirdPartySystemCallLog);

                _thirdPartyCallHelper.Save(thirdPartySystemCallLog);//保存至数据库
            }
            Console.WriteLine($"2.-----第三方日志-同步拦截器");
        }

        protected override async Task InternalInterceptAsynchronous(IInvocation invocation)
        {
            MethodAttributes methodAttributes = invocation.Method.Attributes;
            //var attribute = customAttribute.FirstOrDefault(x => x.AttributeType == typeof(ThridPartyCallLogAttribute)); 
            Console.WriteLine($"1.-----第三方日志-异步拦截器");
            var thirdPartySystemCallLog = _thirdPartyCallHelper.CreateThirdPartySystemCallLog(invocation);
            bool isSuccess = true;
            string errorInfo = string.Empty;
            var proceedInfo = invocation.CaptureProceedInfo();
            try
            {
                proceedInfo.Invoke();
                var task = (Task) invocation.ReturnValue;
                await task.ConfigureAwait(false);
            }
            catch (Exception e)
            {
                isSuccess = false;
                errorInfo = $"{e.Message}；堆栈信息：{e.StackTrace}";
            }
            finally
            {
                thirdPartySystemCallLog.NatrualKeyId = Guid.Empty;//暂时无法获取
                thirdPartySystemCallLog.SourceSystem = "";//暂时无法获取
                thirdPartySystemCallLog.IsSuccess = isSuccess;
                thirdPartySystemCallLog.ErrorInfo = errorInfo;
                
                WriteLog(thirdPartySystemCallLog);

                await _thirdPartyCallHelper.SaveAsync(thirdPartySystemCallLog);
            }
            
            
            
            Console.WriteLine($"2.-----第三方日志-异步拦截器");
        }

        protected override async Task<TResult> InternalInterceptAsynchronous<TResult>(IInvocation invocation)
        {
            MethodAttributes methodAttributes = invocation.Method.Attributes;
            Console.WriteLine($"1.-----第三方日志-异步拦截器");
            var thirdPartySystemCallLog = _thirdPartyCallHelper.CreateThirdPartySystemCallLog(invocation);
            string outputParams = string.Empty;
            bool isSuccess = true;
            string errorInfo = string.Empty;
            TResult result = default(TResult);
            try
            {
                var proceedInfo = invocation.CaptureProceedInfo();
                proceedInfo.Invoke();
                var taskResult = (Task<TResult>)invocation.ReturnValue;
                result = await taskResult.ConfigureAwait(false);
                outputParams = JsonConvert.SerializeObject(result);
            }
            catch (Exception e)
            {
                isSuccess = false;
                errorInfo = $"{e.Message}；堆栈信息：{e.StackTrace}";
            }
            finally
            {
                thirdPartySystemCallLog.NatrualKeyId = Guid.Empty;//暂时无法获取
                thirdPartySystemCallLog.SourceSystem = "";//暂时无法获取
            
                thirdPartySystemCallLog.IsSuccess = isSuccess;
                thirdPartySystemCallLog.ResponseData = outputParams;
                thirdPartySystemCallLog.ErrorInfo = errorInfo;

                WriteLog(thirdPartySystemCallLog);

                await _thirdPartyCallHelper.SaveAsync(thirdPartySystemCallLog);//保存至数据库
            }
            
            Console.WriteLine($"2.-----第三方日志-异步拦截器");
            return result;
        }


        private void WriteLog(ThirdPartySystemCallLog log)
        {
            string logStr = JsonConvert.SerializeObject(log);
            Logger.Info($"第三方日志调用：${logStr}");
        }
    }
}